package cn.itcast.webmagic;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.FilePipeline;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;

/**
 * PageProcesser主要是负责页面的解析工作的模块
 * 一共有三种常用的解析方式：
 *      1. Xpath：本质上就是将html层级关系用路径的方式表示出来，从而获取相应标签中的内容
 *
 *      2. Css选择器：本质上和前端写css选择器一样，没有什么区别
 *
 *      3. 正则表达式
 *
 *      上述三个可以组合使用
 */
@SuppressWarnings("all")
public class JobProcesser implements PageProcessor {

    private Site site = new Site().me();

    /**
     * 由于页面的解析，我们需要将解析的数据放置到一个结果集合中，该结果集合本质上就是一个map容器
     * 通过调用putField(key,value)放置解析之后的数据
     * page.putField()放置解析之后的数据
     * page.getHtml() 获取html页面 之后可以通过上述提到的三种选择器来获取页面中需要的数据
     * css("")
     * xpath("")
     * regex("")
     * @param page：存放发起求情之后的html页面数据
     */
    @Override
    public void process(Page page) {
        // css选择器
        Html pageHtml = page.getHtml(); // 获取html页面
        page.putField("div",pageHtml.css("li.fore2 a")); // // 将获取的数据放置到容器中 以键值对的形式存放

        // xpath选择器
        page.putField("J_container_2",pageHtml.xpath("//ul[@id=list-646]/li[@class=_22Oix1ELZz1MDoP6GMIm0F]"));

        // 获取链接   注意到Request对象实际上是对URL的一个封装，简单理解就是一个URL对应一个Request对象
        // 通过addTargetRequest方法来添加链接
        // 添加之后是有WebMagic框架自动帮助我们解析当前天添加的url，当然我们不可能获取所有的url，而是有针对性的获取自己需要的
        // 所以此时我们需要结合上述的选择器挑选出自己需要的链接，进行解析
        // 需要强制转型为Request类型
        page.addTargetRequest((Request) page.getHtml().css("div").links().regex("").all());
    }

    /**
     *  Site的作用：配置爬虫的相关属性(请求属性)
     * @return
     */
    @Override
    public Site getSite() {
        return site
                .setCharset("utf-8") // 设置编码
                .setTimeOut(10000) // 设置超时时间
                .setRetrySleepTime(10000) // 设置重置的睡眠时间
                .setSleepTime(1000); // 设置睡眠时间
    }

    public static void main(String[] args) {
        // 创建一个组织WebMagic的容器Spider
        // 对于组件中的Pipeline而言，用于数据的输出组件
        // 有一个默认值ConsolePipeline，为控制台输出
        // 当然我们可以修改其默认值为FilePipeline ，为输出到本地磁盘的文件中
        // 具体addPipeline(new FilePipeline("路径地址"))
        // 当然我们可以通过实现接口Pipeline来写一个自己需要的输出方式
        Spider.create(new JobProcesser())
                .addUrl("https://kuaibao.jd.com/?ids=214569150,790445,789182,120479403")
                .addPipeline(new FilePipeline("路径地址"))
                .thread(5) // 多线程，设置为5个线程同时爬取数据
                .run();
    }
}
